<!DOCTYPE html><html><head>
      <title>hoymiles-format-description</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      
      
        <script type="text/x-mathjax-config">
          MathJax.Hub.Config({"extensions":["tex2jax.js"],"jax":["input/TeX","output/HTML-CSS"],"messageStyle":"none","tex2jax":{"processEnvironments":false,"processEscapes":true,"inlineMath":[["$","$"],["\\(","\\)"]],"displayMath":[["$$","$$"],["\\[","\\]"]]},"TeX":{"extensions":["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]},"HTML-CSS":{"availableFonts":["TeX"]}});
        </script>
        <script type="text/javascript" async src="file:////home/sthieme/.vscode/extensions/shd101wyy.markdown-preview-enhanced-0.6.3/node_modules/@shd101wyy/mume/dependencies/mathjax/MathJax.js" charset="UTF-8"></script>
        
      
      
      
      
      
      <script type="text/javascript" src="file:////home/sthieme/.vscode/extensions/shd101wyy.markdown-preview-enhanced-0.6.3/node_modules/@shd101wyy/mume/dependencies/wavedrom/default.js" charset="UTF-8"></script><script type="text/javascript" src="file:////home/sthieme/.vscode/extensions/shd101wyy.markdown-preview-enhanced-0.6.3/node_modules/@shd101wyy/mume/dependencies/wavedrom/wavedrom.min.js" charset="UTF-8"></script>
      
      
      
      <style>
      /**
 * prism.js Github theme based on GitHub's theme.
 * @author Sam Clarke
 */
code[class*="language-"],
pre[class*="language-"] {
  color: #333;
  background: none;
  font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
  text-align: left;
  white-space: pre;
  word-spacing: normal;
  word-break: normal;
  word-wrap: normal;
  line-height: 1.4;

  -moz-tab-size: 8;
  -o-tab-size: 8;
  tab-size: 8;

  -webkit-hyphens: none;
  -moz-hyphens: none;
  -ms-hyphens: none;
  hyphens: none;
}

/* Code blocks */
pre[class*="language-"] {
  padding: .8em;
  overflow: auto;
  /* border: 1px solid #ddd; */
  border-radius: 3px;
  /* background: #fff; */
  background: #f5f5f5;
}

/* Inline code */
:not(pre) > code[class*="language-"] {
  padding: .1em;
  border-radius: .3em;
  white-space: normal;
  background: #f5f5f5;
}

.token.comment,
.token.blockquote {
  color: #969896;
}

.token.cdata {
  color: #183691;
}

.token.doctype,
.token.punctuation,
.token.variable,
.token.macro.property {
  color: #333;
}

.token.operator,
.token.important,
.token.keyword,
.token.rule,
.token.builtin {
  color: #a71d5d;
}

.token.string,
.token.url,
.token.regex,
.token.attr-value {
  color: #183691;
}

.token.property,
.token.number,
.token.boolean,
.token.entity,
.token.atrule,
.token.constant,
.token.symbol,
.token.command,
.token.code {
  color: #0086b3;
}

.token.tag,
.token.selector,
.token.prolog {
  color: #63a35c;
}

.token.function,
.token.namespace,
.token.pseudo-element,
.token.class,
.token.class-name,
.token.pseudo-class,
.token.id,
.token.url-reference .token.variable,
.token.attr-name {
  color: #795da3;
}

.token.entity {
  cursor: help;
}

.token.title,
.token.title .token.punctuation {
  font-weight: bold;
  color: #1d3e81;
}

.token.list {
  color: #ed6a43;
}

.token.inserted {
  background-color: #eaffea;
  color: #55a532;
}

.token.deleted {
  background-color: #ffecec;
  color: #bd2c00;
}

.token.bold {
  font-weight: bold;
}

.token.italic {
  font-style: italic;
}


/* JSON */
.language-json .token.property {
  color: #183691;
}

.language-markup .token.tag .token.punctuation {
  color: #333;
}

/* CSS */
code.language-css,
.language-css .token.function {
  color: #0086b3;
}

/* YAML */
.language-yaml .token.atrule {
  color: #63a35c;
}

code.language-yaml {
  color: #183691;
}

/* Ruby */
.language-ruby .token.function {
  color: #333;
}

/* Markdown */
.language-markdown .token.url {
  color: #795da3;
}

/* Makefile */
.language-makefile .token.symbol {
  color: #795da3;
}

.language-makefile .token.variable {
  color: #183691;
}

.language-makefile .token.builtin {
  color: #0086b3;
}

/* Bash */
.language-bash .token.keyword {
  color: #0086b3;
}

/* highlight */
pre[data-line] {
  position: relative;
  padding: 1em 0 1em 3em;
}
pre[data-line] .line-highlight-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  background-color: transparent;
  display: block;
  width: 100%;
}

pre[data-line] .line-highlight {
  position: absolute;
  left: 0;
  right: 0;
  padding: inherit 0;
  margin-top: 1em;
  background: hsla(24, 20%, 50%,.08);
  background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
  pointer-events: none;
  line-height: inherit;
  white-space: pre;
}

pre[data-line] .line-highlight:before, 
pre[data-line] .line-highlight[data-end]:after {
  content: attr(data-start);
  position: absolute;
  top: .4em;
  left: .6em;
  min-width: 1em;
  padding: 0 .5em;
  background-color: hsla(24, 20%, 50%,.4);
  color: hsl(24, 20%, 95%);
  font: bold 65%/1.5 sans-serif;
  text-align: center;
  vertical-align: .3em;
  border-radius: 999px;
  text-shadow: none;
  box-shadow: 0 1px white;
}

pre[data-line] .line-highlight[data-end]:after {
  content: attr(data-end);
  top: auto;
  bottom: .4em;
}html body{font-family:"Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif;font-size:16px;line-height:1.6;color:#333;background-color:#fff;overflow:initial;box-sizing:border-box;word-wrap:break-word}html body>:first-child{margin-top:0}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{line-height:1.2;margin-top:1em;margin-bottom:16px;color:#000}html body h1{font-size:2.25em;font-weight:300;padding-bottom:.3em}html body h2{font-size:1.75em;font-weight:400;padding-bottom:.3em}html body h3{font-size:1.5em;font-weight:500}html body h4{font-size:1.25em;font-weight:600}html body h5{font-size:1.1em;font-weight:600}html body h6{font-size:1em;font-weight:600}html body h1,html body h2,html body h3,html body h4,html body h5{font-weight:600}html body h5{font-size:1em}html body h6{color:#5c5c5c}html body strong{color:#000}html body del{color:#5c5c5c}html body a:not([href]){color:inherit;text-decoration:none}html body a{color:#08c;text-decoration:none}html body a:hover{color:#00a3f5;text-decoration:none}html body img{max-width:100%}html body>p{margin-top:0;margin-bottom:16px;word-wrap:break-word}html body>ul,html body>ol{margin-bottom:16px}html body ul,html body ol{padding-left:2em}html body ul.no-list,html body ol.no-list{padding:0;list-style-type:none}html body ul ul,html body ul ol,html body ol ol,html body ol ul{margin-top:0;margin-bottom:0}html body li{margin-bottom:0}html body li.task-list-item{list-style:none}html body li>p{margin-top:0;margin-bottom:0}html body .task-list-item-checkbox{margin:0 .2em .25em -1.8em;vertical-align:middle}html body .task-list-item-checkbox:hover{cursor:pointer}html body blockquote{margin:16px 0;font-size:inherit;padding:0 15px;color:#5c5c5c;background-color:#f0f0f0;border-left:4px solid #d6d6d6}html body blockquote>:first-child{margin-top:0}html body blockquote>:last-child{margin-bottom:0}html body hr{height:4px;margin:32px 0;background-color:#d6d6d6;border:0 none}html body table{margin:10px 0 15px 0;border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}html body table th{font-weight:bold;color:#000}html body table td,html body table th{border:1px solid #d6d6d6;padding:6px 13px}html body dl{padding:0}html body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:bold}html body dl dd{padding:0 16px;margin-bottom:16px}html body code{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;font-size:.85em !important;color:#000;background-color:#f0f0f0;border-radius:3px;padding:.2em 0}html body code::before,html body code::after{letter-spacing:-0.2em;content:"\00a0"}html body pre>code{padding:0;margin:0;font-size:.85em !important;word-break:normal;white-space:pre;background:transparent;border:0}html body .highlight{margin-bottom:16px}html body .highlight pre,html body pre{padding:1em;overflow:auto;font-size:.85em !important;line-height:1.45;border:#d6d6d6;border-radius:3px}html body .highlight pre{margin-bottom:0;word-break:normal}html body pre code,html body pre tt{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}html body pre code:before,html body pre tt:before,html body pre code:after,html body pre tt:after{content:normal}html body p,html body blockquote,html body ul,html body ol,html body dl,html body pre{margin-top:0;margin-bottom:16px}html body kbd{color:#000;border:1px solid #d6d6d6;border-bottom:2px solid #c7c7c7;padding:2px 4px;background-color:#f0f0f0;border-radius:3px}@media print{html body{background-color:#fff}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{color:#000;page-break-after:avoid}html body blockquote{color:#5c5c5c}html body pre{page-break-inside:avoid}html body table{display:table}html body img{display:block;max-width:100%;max-height:100%}html body pre,html body code{word-wrap:break-word;white-space:pre}}.markdown-preview{width:100%;height:100%;box-sizing:border-box}.markdown-preview .pagebreak,.markdown-preview .newpage{page-break-before:always}.markdown-preview pre.line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}.markdown-preview pre.line-numbers>code{position:relative}.markdown-preview pre.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:1em;font-size:100%;left:0;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-preview pre.line-numbers .line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.markdown-preview pre.line-numbers .line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}.markdown-preview .mathjax-exps .MathJax_Display{text-align:center !important}.markdown-preview:not([for="preview"]) .code-chunk .btn-group{display:none}.markdown-preview:not([for="preview"]) .code-chunk .status{display:none}.markdown-preview:not([for="preview"]) .code-chunk .output-div{margin-bottom:16px}.scrollbar-style::-webkit-scrollbar{width:8px}.scrollbar-style::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}.scrollbar-style::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,0.66);border:4px solid rgba(150,150,150,0.66);background-clip:content-box}html body[for="html-export"]:not([data-presentation-mode]){position:relative;width:100%;height:100%;top:0;left:0;margin:0;padding:0;overflow:auto}html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{position:relative;top:0}@media screen and (min-width:914px){html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{padding:2em calc(50% - 457px + 2em)}}@media screen and (max-width:914px){html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for="html-export"]:not([data-presentation-mode]) .markdown-preview{font-size:14px !important;padding:1em}}@media print{html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn{display:none}}html body[for="html-export"]:not([data-presentation-mode]) #sidebar-toc-btn{position:fixed;bottom:8px;left:8px;font-size:28px;cursor:pointer;color:inherit;z-index:99;width:32px;text-align:center;opacity:.4}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] #sidebar-toc-btn{opacity:1}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc{position:fixed;top:0;left:0;width:300px;height:100%;padding:32px 0 48px 0;font-size:14px;box-shadow:0 0 4px rgba(150,150,150,0.33);box-sizing:border-box;overflow:auto;background-color:inherit}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar{width:8px}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,0.66);border:4px solid rgba(150,150,150,0.66);background-clip:content-box}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc a{text-decoration:none}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul{padding:0 1.6em;margin-top:.8em}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc li{margin-bottom:.8em}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc ul{list-style-type:none}html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{left:300px;width:calc(100% -  300px);padding:2em calc(50% - 457px -  150px);margin:0;box-sizing:border-box}@media screen and (max-width:1274px){html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for="html-export"]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{width:100%}}html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .markdown-preview{left:50%;transform:translateX(-50%)}html body[for="html-export"]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .md-sidebar-toc{display:none}
/* Please visit the URL below for more information: */
/*   https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */

      </style>
    </head>
    <body for="html-export">
      <div class="mume markdown-preview  ">
      <table>
<thead>
<tr class="header">
<th><img src="logo1_small.png" alt="Ahoy!"></th>
<th>Ahoy! A Hoymiles DTU Projekt</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<h1 id="inhaltsverzeichnis">Inhaltsverzeichnis</h1>
<ul>
<li><a href="#inhaltsverzeichnis">Inhaltsverzeichnis</a></li>
<li><a href="#ziel-dieses-projekts">Ziel dieses Projekts</a></li>
<li><a href="#about-this-document">About this Document</a>
<ul>
<li><a href="#origin-contributors">Origin, Contributors</a></li>
</ul></li>
<li><a href="#systemaufbau">Systemaufbau</a>
<ul>
<li><a href="#abbildung-1-system&#xFC;bersicht">ABBILDUNG 1:
System&#xFC;bersicht</a>
<ul>
<li><a href="#enhanced-shockburst-esb">Enhanced ShockBurst
(ESB)</a></li>
</ul></li>
<li><a href="#abbildung-2-innerer-aufbau-dtu">ABBILDUNG 2: Innerer
Aufbau &#x201C;DTU&#x201D;</a>
<ul>
<li><a href="#oberseite-gigadevices-gd32f303-espressif-esp-12f">Oberseite:
GigaDevices GD32F303, Espressif ESP-12F</a></li>
<li><a href="#unterseite-nordic-semiconductors-nrf12le1e">Unterseite:
Nordic Semiconductors nRF12LE1E</a></li>
</ul></li>
<li><a href="#abbildung-3-detailansicht-gd32f303---nrf24le1e">ABBILDUNG
3: Detailansicht GD32F303 - NRF24LE1E</a>
<ul>
<li><a href="#detail-oberseite-gigadevices-gd32f303-winbond-25012">Detail
Oberseite: GigaDevices GD32F303, Winbond 25012</a></li>
<li><a href="#detail-unterseite-nordic-semiconductors-nrf12le1e-2401c">Detail
Unterseite: Nordic Semiconductors nRF12LE1E, 2401C</a></li>
<li><a href="#diagramm-nordic-kommunikations-schema">Diagramm: Nordic
Kommunikations Schema</a></li>
<li><a href="#detail-unterseite-rxtx-zwischen-gd32f303-und-nrf12le1e-testpunkte-f&#xFC;r-swd-port-und-usb-schnittstelle">Detail
Unterseite: RX/TX zwischen GD32F303 und nRF12LE1E, Testpunkte f&#xFC;r SWD
Port und USB Schnittstelle</a></li>
<li><a href="#diagramm-test-setup-mit-logic-analyser-hackrf-und-zwei-nrf24-sniffern">Diagramm:
Test Setup mit Logic Analyser, HackRF und zwei NRf24 Sniffern</a></li>
</ul></li>
</ul></li>
<li><a href="#adressierung">Adressierung</a>
<ul>
<li><a href="#abbildung-4-enhanced-shockburst-on-air-data-format">ABBILDUNG 4:
Enhanced Shockburst On-Air Data Format</a></li>
</ul></li>
<li><a href="#seriennummern">Seriennummern</a></li>
<li><a href="#nachrichten">Nachrichten</a>
<ul>
<li><a href="#encapsulated-packets">Encapsulated Packets</a>
<ul>
<li><a href="#nachricht-dtu-an-wr-init-">Nachricht: DTU an WR: &#x201C;Init&#x201D;
(?)</a></li>
<li><a href="#nachricht-dtu-an-wr-init-2-">Nachricht: DTU an WR: &#x201C;Init
2&#x201D; (?)</a></li>
<li><a href="#nachricht-0x80-dtu-an-wr-zeit-setzen-">Nachricht 0x80: DTU
an WR: &#x201C;Zeit setzen&#x201D; (?)</a></li>
<li><a href="#nachricht-0x81-dtu-an-wr-anfrage-dc-daten-">Nachricht
0x81: DTU an WR: &#x201C;Anfrage DC-Daten&#x201D; (?)</a></li>
<li><a href="#nachricht-0x82-dtu-an-wr-anfrage-ac-daten-">Nachricht
0x82: DTU an WR: &#x201C;Anfrage AC-Daten&#x201D; (?)</a></li>
<li><a href="#nachricht-0x83-dtu-an-wr-anfrage-dc-daten-">Nachricht
0x83: DTU an WR: &#x201C;Anfrage DC-Daten&#x201D; (?)</a></li>
<li><a href="#nachricht-0x85-dtu-an-wr--">Nachricht 0x85: DTU an WR:
&#x201C;???&#x201D; (?)</a></li>
<li><a href="#nachricht-0xff-dtu-an-wr--">Nachricht 0xFF: DTU an WR:
&#x201C;???&#x201D; (?)</a></li>
<li><a href="#nachricht-0x01-wr-an-dtu-aktuelle-dc-daten-">Nachricht
0x01: WR an DTU: &#x201C;Aktuelle DC Daten&#x201D; (?)</a></li>
<li><a href="#nachricht-0x02-wr-an-dtu-aktuelle-ac-daten-">Nachricht
0x02: WR an DTU: &#x201C;Aktuelle AC Daten&#x201D; (?)</a></li>
<li><a href="#nachricht-0x83-wr-an-dtu---nach-cmd-w&#xE4;re-das-eher-auch-eine-antwort-vom-wr">Nachricht
0x83: WR an DTU (?): &#x201C;???&#x201D; (nach CMD w&#xE4;re das eher auch eine Antwort vom
WR?)</a></li>
</ul></li>
<li><a href="#hinweise">Hinweise</a></li>
<li><a href="#enhanced-shockburst-payloads">Enhanced Shockburst
Payloads</a>
<ul>
<li><a href="#cmd-0x80-dtu----wr-set-timedate-">CMD 0x80: DTU &#x2013;&gt; WR:
&#x201C;Set time/date&#x201D; (?)</a></li>
<li><a href="#cmd-0x01-wr----dtu-current-dc-data--shown-for-an-hm-700-and-hm-400">CMD
0x01: WR &#x2013;&gt; DTU: &#x201C;Current DC data&#x201D; (?) (shown for an HM-700 and
HM-400)</a></li>
<li><a href="#nachricht-0x02-wr-an-dtu-aktuelle-ac-daten--1">Nachricht
0x02: WR an DTU: &#x201C;Aktuelle AC Daten&#x201D; (?)</a></li>
<li><a href="#cmd-0x82-wr----dtu---shown-for-an-hm-400">CMD 0x82: WR
&#x2013;&gt; DTU: &#x201C;???&#x201D; (?) (shown for an HM-400)</a></li>
<li><a href="#nachricht-0x83-wr-an-dtu---nach-cmd-w&#xE4;re-das-eher-auch-eine-antwort-vom-wr-1">Nachricht
0x83: WR an DTU (?): &#x201C;???&#x201D; (nach CMD w&#xE4;re das eher auch eine Antwort vom
WR?)</a></li>
</ul></li>
</ul></li>
<li><a href="#legend">Legend</a></li>
<li><a href="#glossary">Glossary</a></li>
<li><a href="#notizen">Notizen</a></li>
<li><a href="#references">References</a></li>
<li><a href="#revision-history">Revision History</a></li>
</ul>
<h1 id="ziel-dieses-projekts">Ziel dieses Projekts</h1>
<p>Anstelle der DTU wollen wir direkt von einem Arduino/RaspberryPi o.&#xE4;.
die aktuellen Betriebsdaten der Wechselrichter auslesen.</p>
<p>Ohne Umweg &#xFC;ber die &#x201C;S-Miles Cloud&#x201D;.</p>
<p>Das Projekt basiert auf den Diskussionen und Erkenntnissen im
Mikrocontroller Forum <a href="https://www.mikrocontroller.net/topic/525778">Wechselrichter
Hoymiles HM-xxxx 2,4 GhZ Nordic Protokoll?</a> [1.].</p>
<h1 id="about-this-document">About this Document</h1>
<p>This description aims to document the data format that Hoymiles micro
inverters use to communicate their current operating state.</p>
<p>The original Hoymiles setup requires connectivity to &#x201C;the cloud&#x201D;, see
<a href="#system-description">this section below</a>.</p>
<p>With the information documented here, it is possible to interact with
a set of Hoymiles micro inverters in a purely &#x201C;offline&#x201D; way, i.e.
without requiring internet access or any connectivity to a &#x201C;cloud&#x201D;.</p>
<p>The only required hardware is a Nordic &#x201C;NRF24L01+&#x201D; wireless
module.</p>
<p>The <code>ahoy</code> project at <a href="https://github.com/grindylow/ahoy">AHOY Communications Project</a>
[6.] collects software for various platforms, including Arduino and
RaspberryPi.</p>
<blockquote>
<p>Note: Some of the sections in this document are (still) in German.
Translations may be provided if and when necessary.</p>
</blockquote>
<h2 id="origin-contributors">Origin, Contributors</h2>
<p>The information in this document was gathered in a large community
effort which started out with <a href="https://www.mikrocontroller.net/topic/525778">this post that
started the community effort</a> [1.] on the German <a href="https://www.mikrocontroller.net">mikrocontroller.net</a> [2.]
forum.</p>
<p>As of April 2022, this effort is still ongoing. Not all details have
been documented yet, and not all secrets have been uncovered.</p>
<p>Multiple members of the community have already successfully retrieved
(and continue to successfully retrieve) data from their Hoymiles micro
inverters.</p>
<p>Here&#x2019;s a list of some of the early contributors:</p>
<ul>
<li>sorbit: created the original mikrocontroller.net thread</li>
<li>Martin (Gast): DTU and RF analysis</li>
<li>Hubi: protocol analysis</li>
<li>Marcel: initial analysis and much logging and interpretation</li>
<li>Pascal A. (pasarn): various datagram fields, crc8</li>
<li>Frank H. (fh_): discovered time_t</li>
<li>Thomas B. (tbnobody): protocol analysis, logging</li>
<li>Arnaldo G. (arnaldo_g): data capturing</li>
<li>Oliver F (of22): protocol analysis, logging</li>
<li>Martin G. (petersilie): protocol analysis, logging, RaspberryPi</li>
</ul>
<h1 id="systemaufbau">Systemaufbau</h1>
<p>Ein Setup wie von Hoymiles vorgesehen, sieht wie folgt aus:</p>
<ul>
<li>Eine &#x201C;DTU&#x201D; kommuniziert mit vielen Wechselrichtern.</li>
<li>Die Kommunikation geht immer von der DTU aus: DTU stellt Anfrage und
erwartet eine Antwort vom WR.</li>
<li>Daf&#xFC;r muss die DTU die Adressen (=Seriennummern) aller WR
kennen.</li>
<li>Diese werden der DTU im Rahmen eines Einrichtungsprozesses
beigebracht.</li>
</ul>
<h3 id="abbildung-1-system&#xFC;bersicht">ABBILDUNG 1: System&#xFC;bersicht</h3>
<p code_chunk_offset="0" cmd="true" args="[&quot;-E&quot;]"><!--?xml version='1.0' encoding='UTF-8' standalone='no'?-->
<svg xmlns="http://www.w3.org/2000/svg" width="490" height="280" shape-rendering="geometricPrecision" version="1.0">
  <defs>
    <filter id="f2" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="5" dy="5"/>
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
    </filter>
  </defs>
  <g stroke-width="1" stroke-linecap="square" stroke-linejoin="round">
    <rect x="0" y="0" width="490" height="280" style="fill: #ffffff"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M305.0 147.0 L425.0 147.0 L425.0 119.0 L305.0 119.0 z"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M135.0 119.0 L135.0 147.0 L55.0 147.0 L55.0 119.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M305.0 147.0 L425.0 147.0 L425.0 119.0 L305.0 119.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M445.0 175.0 L465.0 175.0 L465.0 203.0 L345.0 203.0 L345.0 189.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M135.0 119.0 L135.0 147.0 L55.0 147.0 L55.0 119.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M445.0 175.0 L325.0 175.0 L325.0 161.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M425.0 147.0 L445.0 147.0 L445.0 175.0 "/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M130.0 84.0 L120.0 91.0 L130.0 98.0 z"/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M300.0 84.0 L310.0 91.0 L300.0 98.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M360.0 161.0 L369.0 161.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M380.0 189.0 L389.0 189.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M340.0 133.0 L349.0 133.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M95.0 105.0 L95.0 91.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M125.0 91.0 L305.0 91.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-dasharray="5.000000,5.000000" stroke-miterlimit="0" stroke-linecap="butt" stroke-linejoin="round" fill="white" d="M395.0 231.0 L395.0 217.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M335.0 105.0 L335.0 91.0 "/>
    <text x="81" y="138" font-family="Courier" font-size="13" stroke="none" fill="#000000">DTU</text>
    <text x="103" y="250" font-family="Courier" font-size="14" stroke="none" fill="#000000">ABBILDUNG 1</text>
    <text x="236" y="250" font-family="Courier" font-size="15" stroke="none" fill="#000000">System&#xFC;bersicht</text>
    <text x="190" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">Nordic</text>
    <text x="150" y="68" font-family="Courier" font-size="15" stroke="none" fill="#000000">&quot;Enh. Shockburst&quot;</text>
    <text x="190" y="82" font-family="Courier" font-size="15" stroke="none" fill="#000000">2.4 GHz</text>
    <text x="88" y="96" font-family="Courier" font-size="15" stroke="none" fill="#000000">\ /</text>
    <text x="343" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">MI 1500</text>
    <text x="328" y="96" font-family="Courier" font-size="15" stroke="none" fill="#000000">\ /</text>
    <text x="369" y="194" font-family="Courier" font-size="15" stroke="none" fill="#000000">MI ...</text>
    <text x="323" y="138" font-family="Courier" font-size="15" stroke="none" fill="#000000">MI 600</text>
  </g>
</svg></p>
<h4 id="enhanced-shockburst-esb">Enhanced ShockBurst (ESB)</h4>
<p>ESB features automatic packet transaction handling for easy
implementation of a reliable bidirectional data link. A transaction is a
packet exchange between two transceivers, with one transceiver acting as
the Primary Receiver (PRX) and the other transceiver acting as the
Primary Transmitter (PTX).</p>
<figure>
<img src="protocol/2022-03-25_11_02_44-Window.png" alt="Protocol RX/TX">
<figcaption aria-hidden="true">Protocol RX/TX</figcaption>
</figure>
<h3 id="abbildung-2-innerer-aufbau-dtu">ABBILDUNG 2: Innerer Aufbau
&#x201C;DTU&#x201D;</h3>
<p code_chunk_offset="1" cmd="true" args="[&quot;-E&quot;]"><!--?xml version='1.0' encoding='UTF-8' standalone='no'?-->
<svg xmlns="http://www.w3.org/2000/svg" width="470" height="280" shape-rendering="geometricPrecision" version="1.0">
  <defs>
    <filter id="f2" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="5" dy="5"/>
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
    </filter>
  </defs>
  <g stroke-width="1" stroke-linecap="square" stroke-linejoin="round">
    <rect x="0" y="0" width="470" height="280" style="fill: #ffffff"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M305.0 147.0 L425.0 147.0 L425.0 119.0 L305.0 119.0 z"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M285.0 189.0 L285.0 217.0 L175.0 217.0 L175.0 189.0 z"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M145.0 119.0 L145.0 147.0 L45.0 147.0 L45.0 119.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M305.0 147.0 L425.0 147.0 L425.0 119.0 L305.0 119.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M285.0 189.0 L285.0 217.0 L175.0 217.0 L175.0 189.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M145.0 119.0 L145.0 147.0 L45.0 147.0 L45.0 119.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M155.0 203.0 L95.0 203.0 L95.0 161.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M305.0 203.0 L365.0 203.0 L365.0 161.0 "/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M95.0 154.0 L90.0 168.0 L100.0 168.0 z"/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M365.0 154.0 L360.0 168.0 L370.0 168.0 z"/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M150.0 196.0 L160.0 203.0 L150.0 210.0 z"/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M310.0 196.0 L300.0 203.0 L310.0 210.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M95.0 105.0 L95.0 91.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M365.0 91.0 L365.0 105.0 "/>
    <text x="61" y="138" font-family="Courier" font-size="14" stroke="none" fill="#000000">ESP8266</text>
    <text x="73" y="250" font-family="Courier" font-size="14" stroke="none" fill="#000000">ABBILDUNG 2</text>
    <text x="113" y="222" font-family="Courier" font-size="15" stroke="none" fill="#000000">(B)</text>
    <text x="211" y="250" font-family="Courier" font-size="15" stroke="none" fill="#000000">Innerer Aufbau &quot;DTU&quot;</text>
    <text x="82" y="67" font-family="Courier" font-size="11" stroke="none" fill="#000000">WLAN</text>
    <text x="88" y="96" font-family="Courier" font-size="15" stroke="none" fill="#000000">\ /</text>
    <text x="192" y="208" font-family="Courier" font-size="13" stroke="none" fill="#000000">GD32F303</text>
    <text x="330" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">Nordic</text>
    <text x="290" y="68" font-family="Courier" font-size="15" stroke="none" fill="#000000">&quot;Enh. Shockburst&quot;</text>
    <text x="330" y="82" font-family="Courier" font-size="15" stroke="none" fill="#000000">2.4 GHz</text>
    <text x="358" y="96" font-family="Courier" font-size="15" stroke="none" fill="#000000">\ /</text>
    <text x="322" y="138" font-family="Courier" font-size="14" stroke="none" fill="#000000">NRF24LE1E</text>
    <text x="323" y="222" font-family="Courier" font-size="15" stroke="none" fill="#000000">(C)</text>
  </g>
</svg></p>
<h4 id="oberseite-gigadevices-gd32f303-espressif-esp-12f">Oberseite:
GigaDevices GD32F303, Espressif ESP-12F</h4>
<figure>
<img src="schematic/dtu_top.jpg" alt="DTU-lite-S top view">
<figcaption aria-hidden="true">DTU-lite-S top view</figcaption>
</figure>
<h4 id="unterseite-nordic-semiconductors-nrf12le1e">Unterseite: Nordic
Semiconductors nRF12LE1E</h4>
<figure>
<img src="schematic/dtu_bot.jpg" alt="DTU-lite-S bottom view">
<figcaption aria-hidden="true">DTU-lite-S bottom view</figcaption>
</figure>
<h3 id="abbildung-3-detailansicht-gd32f303-nrf24le1e">ABBILDUNG 3:
Detailansicht GD32F303 - NRF24LE1E</h3>
<p code_chunk_offset="2" cmd="true" args="[&quot;-E&quot;]"><!--?xml version='1.0' encoding='UTF-8' standalone='no'?-->
<svg xmlns="http://www.w3.org/2000/svg" width="620" height="210" shape-rendering="geometricPrecision" version="1.0">
  <defs>
    <filter id="f2" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="5" dy="5"/>
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
    </filter>
  </defs>
  <g stroke-width="1" stroke-linecap="square" stroke-linejoin="round">
    <rect x="0" y="0" width="620" height="210" style="fill: #ffffff"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M255.0 91.0 L445.0 91.0 L445.0 147.0 L255.0 147.0 z"/>
    <path stroke="gray" fill="gray" filter="url(#f2)" d="M55.0 105.0 L55.0 133.0 L165.0 133.0 L165.0 105.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M255.0 91.0 L445.0 91.0 L445.0 147.0 L255.0 147.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M55.0 105.0 L55.0 133.0 L165.0 133.0 L165.0 105.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M525.0 91.0 L525.0 119.0 L455.0 119.0 "/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M190.0 112.0 L180.0 119.0 L190.0 126.0 z"/>
    <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M240.0 112.0 L250.0 119.0 L240.0 126.0 z"/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M410.0 175.0 L419.0 175.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M185.0 119.0 L245.0 119.0 "/>
    <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M325.0 105.0 L325.0 147.0 "/>
    <text x="72" y="124" font-family="Courier" font-size="13" stroke="none" fill="#000000">GD32F303</text>
    <text x="53" y="180" font-family="Courier" font-size="14" stroke="none" fill="#000000">ABBILDUNG 3</text>
    <text x="193" y="180" font-family="Courier" font-size="15" stroke="none" fill="#000000">Detailansicht GD32F303</text>
    <text x="280" y="124" font-family="Courier" font-size="13" stroke="none" fill="#000000">&#xB5;C</text>
    <text x="292" y="82" font-family="Courier" font-size="14" stroke="none" fill="#000000">NRF24LE1E</text>
    <text x="203" y="138" font-family="Courier" font-size="15" stroke="none" fill="#000000">(C)</text>
    <text x="343" y="124" font-family="Courier" font-size="13" stroke="none" fill="#000000">NRF24L01+</text>
    <text x="432" y="180" font-family="Courier" font-size="14" stroke="none" fill="#000000">NRF24LE1E</text>
    <text x="490" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">Nordic</text>
    <text x="440" y="68" font-family="Courier" font-size="15" stroke="none" fill="#000000">&quot;Enh. Shockburst&quot;</text>
    <text x="490" y="82" font-family="Courier" font-size="15" stroke="none" fill="#000000">2.4 GHz</text>
    <text x="518" y="96" font-family="Courier" font-size="15" stroke="none" fill="#000000">\ /</text>
  </g>
</svg></p>
<h4 id="detail-oberseite-gigadevices-gd32f303-winbond-25012">Detail
Oberseite: GigaDevices GD32F303, Winbond 25012</h4>
<figure>
<img src="schematic/dtu_gd32.jpg" alt="DTU-lite-S MCU GigaDevice GD32F303 RET6 CK8FTY JC2108">
<figcaption aria-hidden="true">DTU-lite-S MCU GigaDevice GD32F303 RET6
CK8FTY JC2108</figcaption>
</figure>
<h4 id="detail-unterseite-nordic-semiconductors-nrf12le1e-2401c">Detail
Unterseite: Nordic Semiconductors nRF12LE1E, 2401C</h4>
<figure>
<img src="schematic/dtu_nrf24.jpg" alt="DTU-lite-S BLE transceiver Nordic Semiconductors NRF24LE1E2114KB MCU">
<figcaption aria-hidden="true">DTU-lite-S BLE transceiver Nordic
Semiconductors NRF24LE1E2114KB MCU</figcaption>
</figure>
<h4 id="diagramm-nordic-kommunikations-schema">Diagramm: Nordic
Kommunikations Schema</h4>
<figure>
<img src="schematic/Comm_Schema.png" alt="DTU-lite-S Kommunikations Schema">
<figcaption aria-hidden="true">DTU-lite-S Kommunikations
Schema</figcaption>
</figure>
<h4 id="detail-unterseite-rxtx-zwischen-gd32f303-und-nrf12le1e-testpunkte-f&#xFC;r-swd-port-und-usb-schnittstelle">Detail
Unterseite: RX/TX zwischen GD32F303 und nRF12LE1E, Testpunkte f&#xFC;r SWD
Port und USB Schnittstelle</h4>
<figure>
<img src="schematic/rx_tx.jpg" alt="DTU-lite-S RX/TX">
<figcaption aria-hidden="true">DTU-lite-S RX/TX</figcaption>
</figure>
<h4 id="diagramm-test-setup-mit-logic-analyser-hackrf-und-zwei-nrf24-sniffern">Diagramm:
Test Setup mit Logic Analyser, HackRF und zwei NRf24 Sniffern</h4>
<figure>
<img src="schematic/test_setup.png" alt="DTU-lite-S Test Setup">
<figcaption aria-hidden="true">DTU-lite-S Test Setup</figcaption>
</figure>
<h1 id="adressierung">Adressierung</h1>
<p>Die Seriennummern der DTU und der WR werden wie folgt als Adressen
f&#xFC;r die Kommunikation verwendet:</p>
<p><strong>Interne Kommunikation</strong>: Die meisten Datenpakete
enthalten Quell- und Zieladresse der jeweiligen Gespr&#xE4;chspartner. Hier
werden 4-Byte-Adressen verwendet, die direkt aus den letzten 8 Stellen
der Seriennummer des Wechselrichters bzw. der DTU gewonnen werden:</p>
<p>Beispiel: Seriennummer <code>....72818832</code></p>
<p>Innerhalb der Pakete auf (C) wird daraus die 4-Byte-Adresse
<code>0x72, 0x81, 0x88, 0x32</code> gebildet. Das ist die
BCD-Darstellung der letzen 8 Dezimalziffern.</p>
<p><strong>NRF24-Kommunikation</strong>: Die zugeh&#xF6;rige Shockburst
Zieladresse ist &#xE4;hnlich, aber die Byte-Reihenfolge wird umgedreht, und
es wird ein <code>0x01</code>-Byte am Ende erg&#xE4;nzt (Shockburst ist auf
5-Byte-Adressen eingestellt).</p>
<p>Um eine Nachricht an das Ger&#xE4;t mit o.g. Seriennummer zu senden lautet
die Shockburst-Zieladresse also
(<code>0x32, 0x88, 0x81, 0x72, 0x01</code>).</p>
<p><strong>NRF24 addressing scheme</strong>: Over the air, the inverters
communicate using the [Nordic &#x201C;Enhanced Shockburst&#x201D; Protocol][3]
configured for 5-byte addresses.</p>
<p>The inverter serial number is converted into a &#x201C;Shockburst&#x201D; address
as follows:</p>
<ul>
<li>encode the final 8 digits of the serial number in BCD format:<br>
<code>0x72, 0x81, 0x88, 0x32</code></li>
<li>reverse the order of the bytes:
<code>0x32, 0x88, 0x81, 0x72</code></li>
<li>append a byte containing 0x01:
<code>0x32, 0x88, 0x81, 0x72, 0x01</code></li>
</ul>
<p>In this example, the resulting &#x201C;Shockburst&#x201D; address is:
0x3288817201.</p>
<p><strong>Additional example</strong>, this time for inverter with
serial number <code>99973104619</code>:</p>
<p>The datasheet specifies the over-the-air packet format: &#x201C;Most
Significant Byte (MSB) to the left&#x201D; (cf [datasheet figure 11][3])</p>
<p><code>Address := Byte_4, Byte_3, Byte_2, Byte_1, Byte_0</code>
(&#x201C;LSByte must be unique&#x201D;)</p>
<p>so <code>0x1946107301</code> results in</p>
<p><code>19 46 10 73 01</code> &#x201C;on the wire&#x201D;</p>
<p>Old-style NRF Libraries take <code>uint64_t</code> addresses. In this
case, the correct address to pass to the library would be
<code>(uint64_t)0x1946107301ULL</code>.</p>
<p>The [&#x201C;Optimized high speed nRF24L01+
driver&#x201D;]](https://nrf24.github.io) [4.] actually wants
<code>uint8_t*</code>, which maybe makes more sense. But apparently it
still wants the bytes in order LSB to MSB (even though the chip will
then put them out in MSB-to-LSB order.</p>
<p>So in this case, the correct sequence of bytes to pass to the library
would be <code>\x01\x73\x10\x46\x19</code>.</p>
<p>Figure 4 below is an annotated example of an &#x201C;Enhanced Shockburst&#x201D;
packet as seen on the air.</p>
<h3 id="abbildung-4-enhanced-shockburst-on-air-data-format">ABBILDUNG 4:
Enhanced Shockburst On-Air Data Format</h3>
<div class="code-chunk" data-id="code-chunk-id-0" data-cmd="dita"><div class="input-div"><pre class="text language-text language-dita" data-role="codeBlock" data-info="dita {code_chunk_offset=3, cmd=true args=[&quot;-E&quot;]}"><code>+----------+--------------------+--------------------+---------------------+------------+
| preamble | dst 5-byte-address | PCF (9-bit)        | payload (&gt;=1 bytes) | 2-byte-CRC |
+----------+--------------------+--------------------+---------------------+------------+
|          |                    | e.g. 0x0d8:        |                     |            |
|  0x55    | addr[4]...addr[0]  | 0b011011  00  0    |                     |            |
|   or     | MSB ... LSB        | len=27    PID nACK |                     |            |
|  0xAA    |                    |                    |                     |            |
|          |                    | e.g. 0x0da         |                     |            |
|          |                    | 0b011011  01  0    |                     |            |
|          |                    | len027    PID nACK |                     |            |
+----------+--------------------+--------------------+---------------------+------------+

PCF: Packet control field
PID: Packet IDentification (to detect/avoid duplicates), cycles through 0...3

              FIGURE 4: Enhanced Shockburst On-Air Data Format</code></pre><div class="btn-group"><div class="run-btn btn"><span>&#x25B6;&#xFE0E;</span></div><div class="run-all-btn btn">all</div></div><div class="status">running...</div></div><div class="output-div"></div></div>
<h1 id="seriennummern">Seriennummern</h1>
<p>Hier eine auf die ersten vier Stellen gek&#xFC;rzte Liste aus der u.a.
Tabelle</p>
<p>Wie man sehen kann sind die Seriennummern nicht ganz eindeutig. Aber
es sollte von der Zahl der Anschl&#xFC;sse bzw. MPPT die im Wechselrichter
verbaut sind eigentlich hinkommen, so da&#xDF; alle mit der selben
Seriennummer zumindest einen &#xE4;hnlichen inneren Aufbau haben sollten.
Lediglich die maximale Leistung der Kan&#xE4;le scheint sie noch zu
unterscheiden.</p>
<p><a href="Hoymiles-SerialNumbers.xlsx">Hoymiles-SerialNumbers.xlsx</a>
[5.]</p>
<table>
<thead>
<tr class="header">
<th>Name</th>
<th>Seriennummer</th>
<th>Maximale Leistung</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>MI-100</td>
<td><code>1011</code></td>
<td>100 W</td>
</tr>
<tr class="even">
<td>MI-250</td>
<td><code>1020</code></td>
<td>250 W</td>
</tr>
<tr class="odd">
<td>MI-300</td>
<td><code>1021</code> Gen2</td>
<td>300 W (1x380Wpp)</td>
</tr>
<tr class="even">
<td>MI-350</td>
<td><code>1021</code> Gen2</td>
<td>350 W (1x440Wpp)</td>
</tr>
<tr class="odd">
<td>MI-400</td>
<td><code>1021</code> Gen2</td>
<td>400 W (1x500Wpp)</td>
</tr>
<tr class="even">
<td>MI-?</td>
<td><code>1022</code> Gen3</td>
<td></td>
</tr>
<tr class="odd">
<td>MI-500</td>
<td><code>1040</code></td>
<td>500 W</td>
</tr>
<tr class="even">
<td>MI-600</td>
<td><code>1041</code> Gen2</td>
<td>600 W (2x380Wpp)</td>
</tr>
<tr class="odd">
<td>MI-700</td>
<td><code>1041</code> Gen2</td>
<td>700 W (2x440Wpp)</td>
</tr>
<tr class="even">
<td>MI-800</td>
<td><code>1041</code> Gen2</td>
<td>800 W (2x500Wpp)</td>
</tr>
<tr class="odd">
<td>TSOL-M800</td>
<td><code>1041</code></td>
<td>800 W</td>
</tr>
<tr class="even">
<td>MI-600</td>
<td><code>1042</code> Gen3</td>
<td>600 W (2x380Wpp)</td>
</tr>
<tr class="odd">
<td>MI-700</td>
<td><code>1042</code> Gen3</td>
<td>700 W (2x440Wpp)</td>
</tr>
<tr class="even">
<td>MI-800</td>
<td><code>1042</code> Gen3</td>
<td>800 W (2x500Wpp)</td>
</tr>
<tr class="odd">
<td>MI-1000</td>
<td><code>1060</code></td>
<td>1000 W</td>
</tr>
<tr class="even">
<td>MI-1200</td>
<td><code>1061</code></td>
<td>1200 W</td>
</tr>
<tr class="odd">
<td>MI-1500</td>
<td><code>1061</code></td>
<td>1500 W</td>
</tr>
<tr class="even">
<td>MI-?</td>
<td><code>1062</code></td>
<td></td>
</tr>
<tr class="odd">
<td>HM-300</td>
<td><code>1121</code> Gen3</td>
<td>300VA (1x380Wpp)</td>
</tr>
<tr class="even">
<td>HM-350</td>
<td><code>1121</code> Gen3</td>
<td>350VA (1x440Wpp)</td>
</tr>
<tr class="odd">
<td>HM-400</td>
<td><code>1121</code> Gen3</td>
<td>400VA (1x500Wpp)</td>
</tr>
<tr class="even">
<td>HM-600</td>
<td><code>1141</code> Gen3</td>
<td>600VA (2x380Wpp)</td>
</tr>
<tr class="odd">
<td>HM-700</td>
<td><code>1141</code> Gen3</td>
<td>700VA (2x440Wpp)</td>
</tr>
<tr class="even">
<td>HM-800</td>
<td><code>1141</code> Gen3</td>
<td>800VA (2x500Wpp)</td>
</tr>
<tr class="odd">
<td>HM-1000</td>
<td><code>1161</code> Gen3</td>
<td>1000VA (4x310Wpp)</td>
</tr>
<tr class="even">
<td>HM-1200</td>
<td><code>1161</code> Gen3</td>
<td>1200VA (4x380Wpp)</td>
</tr>
<tr class="odd">
<td>HM-1500</td>
<td><code>1161</code> Gen3</td>
<td>1500VA (4x470Wpp)</td>
</tr>
<tr class="even">
<td>HM-1500</td>
<td><code>1165</code> Gen3</td>
<td></td>
</tr>
<tr class="odd">
<td>DTU-G100</td>
<td><code>10D2</code></td>
<td></td>
</tr>
<tr class="even">
<td>DTU-W100</td>
<td><code>10D3</code></td>
<td></td>
</tr>
<tr class="odd">
<td>DTU-Lite-S</td>
<td><code>10D3</code></td>
<td></td>
</tr>
<tr class="even">
<td>DTU-Lite</td>
<td><code>10D6</code></td>
<td></td>
</tr>
<tr class="odd">
<td>DTU-Pro</td>
<td><code>10F7</code></td>
<td></td>
</tr>
<tr class="even">
<td>DTU-Pro</td>
<td><code>10F8</code></td>
<td></td>
</tr>
<tr class="odd">
<td>DTU-Pro</td>
<td><code>10FA</code></td>
<td></td>
</tr>
<tr class="even">
<td>DTU-Pro</td>
<td><code>10FB</code></td>
<td></td>
</tr>
</tbody>
</table>
<h1 id="nachrichten">Nachrichten</h1>
<p>Initial protocol analysis focused on the data exchanged on link (C)
in figure (3). Not all the frames observed on this link will result in
an actual RF transmission, and some translation/mangling/processing
happens inside the NRF24LE1E, in particular</p>
<ul>
<li>replacement of serial numbers</li>
<li>recalculation of CRCs</li>
</ul>
<p>These packets (which are all framed in 0x7e&#x2026;0x7f bytes) are described
in section <a href="#encapsulated-packets">Encapsulated Packets</a>
below.</p>
<p>More recent efforts focus mainly on the actual &#x201C;Enhanced Shockburst&#x201D;
packets that are transmitted over the air. These packets are described
in section <a href="#Enhanced-Shockburst-Payloads">Enhanced Shockburst
Payloads</a>, and the information contained in this section is more up
to date.</p>
<h2 id="encapsulated-packets">Encapsulated Packets</h2>
<p>These are packets as observed on Link (C) in figure (3).</p>
<h3 id="nachricht-dtu-an-wr-init">Nachricht: DTU an WR: &#x201C;Init&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht: DTU an WR: &quot;Init&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

             7E   07   00 00 00 00      00 00 00 00      00    07    7F
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^            ^^    ^^
Bedeutung    SOF  MID  WR ser#          WR ser#           ?    CRC8  EOF
                                                                ?</code></pre>
<div class="wavedrom"><script type="WaveDrom">{signal: [
  {name:'Clock',     wave: 'p...........' },
  {name:'Data',      wave: 'x345.6.78.9x', data: '7E 07 00000000 00000000 00 07 7F' },
  {name:'Bedeutung', wave: 'x345.6.78.9x', data: 'SOF MID WRser# WRser# ? CRC8? EOF' },
  {name:'Request',   wave: '01.........0' }
],
 head:{
   text:'Nachricht: DTU an WR: "Init" (?)',
   tick:0,
   every:2
 },
 foot:{
   text:'Nachricht 07',
   tock:9
 },
}</script></div>
<h3 id="nachricht-dtu-an-wr-init-2">Nachricht: DTU an WR: &#x201C;Init 2&#x201D;
(?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht: DTU an WR: &quot;Init 2&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

             7E   07   72 81 88 32      72 81 88 32      00    07    7F
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^            ^^    ^^
Bedeutung    SOF  MID  DTU ser#         DTU ser#          ?    CRC8  EOF
Einheit                BCD (letzte 8)   BCD (letzte 8)    ?     ?
Beispiel               72818832         72818832          ?   </code></pre>
<div class="wavedrom"><script type="WaveDrom">{signal: [
  {name:'Clock',     wave: 'p...........' },
  {name:'Data',      wave: 'x345.6.78.9x', data: '7E 07 72818832 72818832 00 07 7F' },
  {name:'Bedeutung', wave: 'x345.6.78.9x', data: 'SOF MID WRser# WRser# ? CRC8? EOF' },
  {name:'Einheit',   wave: 'x..5.6.78.x.', data: 'BCD(last8) BCD(last8) ? ?' },
  {name:'Beispiel',  wave: 'x..5.6.x...x', data: '72818832 72818832' },
  {name:'Request',   wave: '01.........0' }
],
 head:{
   text:'Nachricht: DTU an WR: "Init 2" (?)',
   tick:0,
   every:2
 },
 foot:{
   text:'Nachricht 07',
   tock:9
 },
}</script></div>
<h3 id="nachricht-0x80-dtu-an-wr-zeit-setzen">Nachricht 0x80: DTU an WR:
&#x201C;Zeit setzen&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x80: DTU an WR: &quot;Zeit setzen&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------
                                                            |&lt;-------------CRC16 &apos;modbus&apos; f&#xFC;r CRC_M-----------------&gt;|
             7E   15   72 22 02 00      72 22 02 00      80 0B 00     62 09 04 9b      00 00     00 00   00 00   00 00     F2 68    F0    7F
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^           ^^^^^^^^^^^                                          ^^^^^    ^^    ^^
Bedeutung    SOF  MID  WR ser#          WR ser#          CMD  ?       TIME (UTC)                                           CRC_M    CRC8  EOF
Einheit                BCD (letzte 8)   BCD (letzte 8)        ?       [s]                                                  HI LO   
Beispiel               72220200         72220200              ?       2022-02-13                                              
                                                                      13:16:11</code></pre>
<div class="wavedrom"><script type="WaveDrom">{signal: [
  {name:'Clock',     wave: 'p.......................' },
  {name:'',          wave: '', data: '' , node: '........a.......b......x' },
  {name:'Data',      wave: 'x345.6.7892.34567.89x', data: '7E 15 72220200 72220200 80 0B 00 6209049B 0000 0000 0000 0000 F268 F0 7F'},
  {name:'Bedeutung', wave: 'x345.6.7892.xxxx7.89x', data: 'SOF MID WRser# WRser# CMD ? ? TIME(UTC) CRC_M CRC8 EOF' },
  {name:'Einheit',   wave: 'x..5.6.x892.xxxx7.x9x', data: 'BCD(last8) BCD(last8) ? ? [s] HILO' },
  {name:'Beispiel',  wave: 'x..5.6.x..2.x.......x', data: '72818832 72818832 2022-02-13' },
  {name:'Beispiel',  wave: 'x.........2.x.......x', data: '13:16:11' },
  {name:'Request',   wave: '01..................0' }
],
 edge: [ 'a<->b CRC16 modbus für CRC_M' ],
 head:{
   text:'Nachricht 0x80: DTU an WR: "Zeit setzen" (?)',
   tick:0,
   every:2
 },
 foot:{
   text:'Nachricht 07',
   tock:9
 },
}</script></div>
<h3 id="nachricht-0x81-dtu-an-wr-anfrage-dc-daten">Nachricht 0x81: DTU
an WR: &#x201C;Anfrage DC-Daten&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x81: DTU an WR: &quot;Anfrage DC-Daten&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

GD-&gt;NRF     7E    15   70 51 43 68    70 51 43 68      81     xx       7F     ...... (NOCH NICHT VERIFIZIERT / GESEHEN)
                                      ^^^^^^^^^^^      ^^     ^^       ^^
                                       | (wird von     CMD    CRC8     EOF
                                       | NRF ersetzt)         | (wird von NRF
                                       v                      v neu berechnet)
                                                             
on-air            15   70 51 43 68    70 53 54 53      81     BA
(payload)              ^^^^^^^^^^^    ^^^^^^^^^^^
                       WR ser #       DTU ser #</code></pre>
<div class="wavedrom"><script type="WaveDrom">{signal: [
  {name:'Clock',     wave: 'p..........' },
  {name:'',          wave: '', data: '' },
  {name:'Data',      wave: 'x345.6.7892.........x', data: '7E 15 70514368 70514368 81 xx 7F ...(NOCH_NICHT_VERIFIZIERT_/_GESEHEN)', 
                     node: '......a.c..' },
  {name:'', wave: '', data: ''},
  {name:'on-air (payload)',   
                     wave: 'x.45.6.78x.', data: '15 70514368 70535453 81 BA', 
                     node: '......b.d..' },
  {name:'Bedeutung', wave: 'x..5.6.789x', data: 'WRser# DTUser# CMD CRC8 EOF' },
  {name:'Request',   wave: '01........0' }
],
 edge: [ 'a~>b (wird von NRF ersetzt)', 'c~>d (wird von NRF neu berechnet)' ],
 head:{
   text:'Nachricht 0x81: DTU an WR: "Anfrage DC-Daten" (?)',
   tick:0,
   every:2
 },
 foot:{
   text:'Nachricht 07',
   tock:9
 },
}</script></div>
<h3 id="nachricht-0x82-dtu-an-wr-anfrage-ac-daten">Nachricht 0x82: DTU
an WR: &#x201C;Anfrage AC-Daten&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x82: DTU an WR: &quot;Anfrage AC-Daten&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

GD-&gt;NRF     7E    15   70 51 43 68    70 51 43 68      82     xx       7F     ...... (NOCH NICHT VERIFIZIERT / GESEHEN)
                                      ^^^^^^^^^^^      ^^     ^^       ^^
                                       | (wird von     CMD    CRC8     EOF
                                       | NRF ersetzt)         | (wird von NRF
                                       v                      v neu berechnet)
                                                             
on-air            15   70 51 43 68    70 53 54 53      82     B9
(payload)              ^^^^^^^^^^^    ^^^^^^^^^^^
                       WR ser #       DTU ser #</code></pre>
<div class="wavedrom"><script type="WaveDrom">{signal: [
  {name:'Clock',     wave: 'p..........' },
  {name:'',          wave: '', data: '' },
  {name:'Data',      wave: 'x345.6.7892.........x', data: '7E 15 70514368 70514368 81 xx 7F ...(NOCH_NICHT_VERIFIZIERT_/_GESEHEN)', 
                     node: '......a.c..' },
  {name:'', wave: '', data: ''},
  {name:'on-air (payload)',   
                     wave: 'x.45.6.78x.', data: '15 70514368 70535453 81 BA', 
                     node: '......b.d..' },
  {name:'Bedeutung', wave: 'x..5.6.789x', data: 'WRser# DTUser# CMD CRC8 EOF' },
  {name:'Request',   wave: '01........0' }
],
 edge: [ 'a~>b (wird von NRF ersetzt)', 'c~>d (wird von NRF neu berechnet)' ],
 head:{
   text:'Nachricht 0x81: DTU an WR: "Anfrage DC-Daten" (?)',
   tick:0,
   every:2
 },
 foot:{
   text:'Nachricht 07',
   tock:9
 },
}</script></div>
<h3 id="nachricht-0x83-dtu-an-wr-anfrage-dc-daten">Nachricht 0x83: DTU
an WR: &#x201C;Anfrage DC-Daten&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x83: DTU an WR: &quot;Anfrage DC-Daten&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

GD-&gt;NRF     7E    15   70 51 43 68    70 51 43 68      83     xx       7F     ...... (NOCH NICHT VERIFIZIERT / GESEHEN)
                                      ^^^^^^^^^^^      ^^     ^^       ^^
                                       | (wird von     CMD    CRC8     EOF
                                       | NRF ersetzt)         | (wird von NRF
                                       v                      v neu berechnet)
                                                             
on-air            15   70 51 43 68    70 53 54 53      83     B8
(payload)              ^^^^^^^^^^^    ^^^^^^^^^^^
                       WR ser #       DTU ser #</code></pre>
<h3 id="nachricht-0x85-dtu-an-wr">Nachricht 0x85: DTU an WR: &#x201C;???&#x201D;
(?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x85: DTU an WR: &quot;???&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

GD-&gt;NRF     7E    15   70 51 43 68    70 51 43 68      85     xx       7F     ...... (NOCH NICHT VERIFIZIERT / GESEHEN)
                                      ^^^^^^^^^^^      ^^     ^^       ^^
                                       | (wird von     CMD    CRC8     EOF
                                       | NRF ersetzt)         | (wird von NRF
                                       v                      v neu berechnet)
                                                             
on-air            15   70 51 43 68    70 53 54 53      85     BE
(payload)              ^^^^^^^^^^^    ^^^^^^^^^^^
                       WR ser #       DTU ser #</code></pre>
<h3 id="nachricht-0xff-dtu-an-wr">Nachricht 0xFF: DTU an WR: &#x201C;???&#x201D;
(?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0xFF: DTU an WR: &quot;???&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

GD-&gt;NRF     7E    15   70 51 43 68    70 51 43 68      FF     xx       7F     ...... (NOCH NICHT VERIFIZIERT / GESEHEN)
                                      ^^^^^^^^^^^      ^^     ^^       ^^
                                       | (wird von     CMD    CRC8     EOF
                                       | NRF ersetzt)         | (wird von NRF
                                       v                      v neu berechnet)
                                                             
on-air            15   70 51 43 68    70 53 54 53      FF     C4
(payload)              ^^^^^^^^^^^    ^^^^^^^^^^^
                       WR ser #       DTU ser #</code></pre>
<h3 id="nachricht-0x01-wr-an-dtu-aktuelle-dc-daten">Nachricht 0x01: WR
an DTU: &#x201C;Aktuelle DC Daten&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x01: WR an DTU: &quot;Aktuelle DC Daten&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

             7E   95   72 22 02 00      72 22 02 00      01 00 01      01 4c   03 bd   0c 46     00 b5   00 03   00 05     00 00    BD    7F
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^            ^^^^^   ^^^^^   ^^^^^     ^^^^^   ^^^^^   ^^^^^              ^^    ^^
Bedeutung    SOF  MID  WR ser#          WR ser#          CMD  ?        PV1.u   PV1.i   PV1.p     PV2.u   PV2.i   PV2.p       ?      CRC8  EOF
Einheit                BCD (letzte 8)   BCD (letzte 8)        ?        [0.1V]  [0.01A] [.1W]     [0.1V]  [0.01A] [.1W]       ?     
Beispiel               72220200         72220200              ?        33.2V   9.57A   317.2W    18.1V   0.03A   0.5W        ?     </code></pre>
<h3 id="nachricht-0x02-wr-an-dtu-aktuelle-ac-daten">Nachricht 0x02: WR
an DTU: &#x201C;Aktuelle AC Daten&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x02: WR an DTU: &quot;Aktuelle AC Daten&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

             7E   95   72 22 02 00      72 22 02 00      02 28 23      00 00   24 44   00 3C     00 00   09 0F   13 88     0B D5   83    7F
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^                                              ^^^^^   ^^^^^     ^^^^^   ^^    ^^
Bedeutung    SOF  MID  WR ser#          WR ser#          CMD  ?                  ?       ?               AC.u    AC.f      AC.p    CRC8  EOF
Einheit                BCD (letzte 8)   BCD (letzte 8)        ?                                          [0.1V]  [0.01Hz]  [0.1W]
Beispiel               72220200         72220200              ?                9284    60                231.9V  50.00Hz   302.9W</code></pre>
<h3 id="nachricht-0x83-wr-an-dtu-nach-cmd-w&#xE4;re-das-eher-auch-eine-antwort-vom-wr">Nachricht
0x83: WR an DTU (?): &#x201C;???&#x201D; (nach CMD w&#xE4;re das eher auch eine Antwort vom
WR?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x83: WR an DTU (?): &quot;???&quot; (nach CMD w&#xE4;re das eher auch eine Antwort vom WR?)
----------------------------------------------------------------------------------------------------------------------------------------------

             7E   95   72 22 02 00      72 22 02 00      83 00 03      00 83     03 E8     00 B2     00 0A     FD 26               1E    7F
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^                                                                        ^^    ^^
Bedeutung    SOF  MID  WR ser#          WR ser#          CMD  ?         ?          ?         ?         ?         ?                 CRC8  EOF
Einheit                BCD (letzte 8)   BCD (letzte 8)        ?                                                   
Beispiel               72220200         72220200              ?        131       1000      178       10                                           </code></pre>
<h2 id="hinweise">Hinweise</h2>
<p>Die &#x201C;on-air (payload)&#x201D; Bytes geben nur die Nutzlast der gesendeten
Shockburst-Pakete an. Intern enthalten diese Pakete auch die
Zieladresse, die L&#xE4;nge, eine CRC.</p>
<hr>
<h2 id="enhanced-shockburst-payloads">Enhanced Shockburst Payloads</h2>
<ul>
<li>These are the packets that are exchanged between inverters and DTU
via the Nordic &#x201C;Enhanced Shockburst&#x201D; protocol.</li>
<li>Each payload is preceded by a preamble, and terminated by a 16-bit
CRC, as described in the <a href="https://infocenter.nordicsemi.com/pdf/nRF24LE1_PS_v1.6.pdf">Nordic
NRF24LE01+ datasheet</a> [3.]. See also figure 4 above.</li>
</ul>
<h3 id="cmd-0x80-dtu-wr-set-timedate">CMD 0x80: DTU &#x2013;&gt; WR: &#x201C;Set
time/date&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>CMD 0x80: DTU --&gt; WR: &quot;Set time/date&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------
                                           |&lt;-------------CRC16 &apos;modbus&apos; f&#xFC;r CRC_M-----------------&gt;|
            15   72220200  72220200   80   0B 00    62 09 04 9b       00 00     00 00   00 00   00 00     F2 68    F0  
            ^^   ^^^^^^^^  ^^^^^^^^   ^^   ^^^^^    ^^^^^^^^^^^                 ^^^^^                     ^^^^^    ^^  
Name        MID  DTU_SER#  DTU_SER#   CMD  uk1      TIME (local)                SEQ?                      CRC_M    CRC8
Units            see &quot;addressing&quot;           ?       [s-since-epoch]                                       HI LO   
Example          72220200  72220200         ?       2022-02-13                                               
                                                    13:16:11                                                 </code></pre>
<ul>
<li>This message will cause the inverter to transmit a CMD=0x01,
CMD=0x02, and, occasionally, also a CMD=0x83 message to the DTU with
serial number DTU_SER#.</li>
<li>Values of &#x201C;0xb0, 0x00&#x201D; and &#x201C;0x11, 0x00&#x201D; have been observed for
&#x201C;UK1&#x201D;. Their meaning is unknown.</li>
<li>&#x201C;SEQ&#x201D; was observed to contain increasing numbers when sent by a
Hoymiles DTU. In particular, each issued &#x201C;command&#x201D; (e.g.&#xA0;&#x201C;switch
inverter on&#x201D;, &#x201C;switch inverter off&#x201D;) appears to increase this value. A
constant value of 0x0000 or 0x0005 appears to work just fine.</li>
<li>Repeatedly sending the same TIME information (instead of correctly
increasing time) <a href="https://www.mikrocontroller.net/topic/525778?page=2#7021386">has
been shown</a> [1. a)] to result in identical behaviour, the inverter
still replies as described above.</li>
</ul>
<h3 id="cmd-0x01-wr-dtu-current-dc-data-shown-for-an-hm-700-and-hm-400">CMD
0x01: WR &#x2013;&gt; DTU: &#x201C;Current DC data&#x201D; (?) (shown for an HM-700 and
HM-400)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>CMD 0x01: WR --&gt; DTU: &quot;Current DC data&quot; (?) (shown for an HM-700 and HM-400)
----------------------------------------------------------------------------------------------------------------------------------------------
HM-700 (2-channel):
            95   72 22 02 00      72 22 02 00      01 00 01      01 4c   03 bd   0c 46     00 b5   00 03   00 05     00 00    BD    7F
            ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^            ^^^^^   ^^^^^   ^^^^^     ^^^^^   ^^^^^   ^^^^^              ^^    ^^
NameMID          WR ser#          WR ser#          CMD  ?        PV1.u   PV1.i   PV1.p     PV2.u   PV2.i   PV2.p       ?      CRC8  EOF
Units            BCD (letzte 8)   BCD (letzte 8)        ?        [0.1V]  [0.01A] [.1W]     [0.1V]  [0.01A] [.1W]       ?     
Example          72220200         72220200              ?        33.2V   9.57A   317.2W    18.1V   0.03A   0.5W        ?     


HM-400 (1-channel):
byte        00   01 02 03 04      05 06 07 08      09 10 11      12 13   14 15   16 17     18 19   20 21   22 23     24 25  26 27  28    29
            95   73 10 xx yy      73 10 xx yy      01 00 01      01 9A   00 46   01 21     00 00   FA E6   00 84     09 0C  F5 DD  BD    7F
            ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^            ^^^^^   ^^^^^   ^^^^^     ^^^^^^^^^^^^^   ^^^^^     ^^^^^  ^^^^^  ^^    ^^
NameMID          WR ser#          WR ser#          CMD  ?        PV1.u   PV1.i   PV1.p      DC? P total?  DC? P day   V AC         CRC8  EOF
Units            BCD (letzte 8)   BCD (letzte 8)        ?        [0.1V]  [0.01A] [.1W]        [0.001kWh]   [1Wh]     [0.1V]   ?
Example          7310xxyy         7310xxyy              ?        41.0V    0.70A  28.9W        64.23kWh     132Wh     231.6V   ?

legend
PVx.u:    DC voltage of panel x
PVx.i:    DC current of panel x
PVx.p:    DC power of panel x
WR ser#:  inverter serial, e.g. 11217310xxyy (HM-400) =&gt; 7310xxyy
P tot:    DC (or AC)? power total (monthly/yearly?)
P day:    DC (or AC)? power daily
V AC:     AC voltage</code></pre>
<ul>
<li>The exact meaning of the contents of this message varies depending
on inverter type. So far, the following variants have been observed:
<ul>
<li>HM-300/350/400 (single channel):</li>
<li>HM-600/700/800 (2-channel):</li>
<li>HM-1000/1200/1500 (4-channel):</li>
</ul></li>
</ul>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>TODO TODO TODO
73109025   73109025   01        00  01     014F      0003      000B    0000  40AE  03AC     08E6       7C
                                           ^^^^      ^^^^      ^^^^                ^^^^     ^^^^
                                           335       3         11                  940      2278
                                           33.5V     0.03A     1.1W                940W     22.78kW

95     71603546   71603546   01        00  01     015D      004D      00B3    010C  0270  0001     3419       64   B327 B327 1
                                                  ^^^^      ^^^^      ^^^^                ^^^^     ^^^^
                                                  349       77        179                 1        13337
                                                  34.9V     0.77A     1.79W               1        133.37kW</code></pre>
<h3 id="nachricht-0x02-wr-an-dtu-aktuelle-ac-daten-1">Nachricht 0x02: WR
an DTU: &#x201C;Aktuelle AC Daten&#x201D; (?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x02: WR an DTU: &quot;Aktuelle AC Daten&quot; (?)
----------------------------------------------------------------------------------------------------------------------------------------------

             7E   95   72 22 02 00      72 22 02 00      02 28 23      00 00   24 44   00 3C     00 00   09 0F   13 88     0B D5   83  
             ^^   ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^                                              ^^^^^   ^^^^^     ^^^^^   ^^  
Bedeutung    SOF  MID  WR ser#          WR ser#          CMD  ?                  ?       ?               AC.u    AC.f      AC.p    CRC8
Einheit                BCD (letzte 8)   BCD (letzte 8)        ?                                          [0.1V]  [0.01Hz]  [0.1W]
Beispiel               72220200         72220200              ?                9284    60                231.9V  50.00Hz   302.9W</code></pre>
<ul>
<li>The exact meaning of the contents of this message varies depending
on inverter type. So far, the following variants have been observed:
<ul>
<li>until now, message never observed using a HM-400</li>
</ul></li>
</ul>
<h3 id="cmd-0x82-wr-dtu-shown-for-an-hm-400">CMD 0x82: WR &#x2013;&gt; DTU:
&#x201C;???&#x201D; (?) (shown for an HM-400)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>CMD 0x82: WR --&gt; DTU: &quot;???&quot; (?) (shown for an HM-400)
----------------------------------------------------------------------------------------------------------------------------------------------
HM-400 (1-channel):
byte        00   01 02 03 04      05 06 07 08      09  10 11      12 13   14 15   16 17     18 19   20 21   22 23     24 25  26 27  28    29
            95   73 10 xx yy      73 10 xx yy      82  13 8A      01 1C   00 00   00 0C     03 E8   00 65   00 06     3C 1D  36 9E  8D    1
            ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^  ^^^^^      ^^^^^   ^^^^^   ^^^^^     ^^^^^   ^^^^^   ^^^^^     ^^^^^  ^^^^^  ^^    ^^
NameMID          WR ser#          WR ser#          CMD Freq       P AC     ?      I AC        ?     Temp      ?         ?      ?   CRC8?  EOF?
Units            BCD (letzte 8)   BCD (letzte 8)       [0.01Hz]   [0.1W]   ?      [0.01A]     ?    [0.1&#xB0;C]    ?         ?      ?
Example          7310xxyy         7310xxyy             50,02Hz    28,40W   ?      0,120A      ?    10,10&#xB0;C    ?         ?      ?

legend
Freq:     frequency of inverter
P AC:     AC power of inverter
I AC:     AC current of inverter
Temp:     temperature of inverter
WR ser#:  inverter serial, e.g. 11217310xxyy (HM-400) =&gt; 7310xxyy</code></pre>
<h3 id="nachricht-0x83-wr-an-dtu-nach-cmd-w&#xE4;re-das-eher-auch-eine-antwort-vom-wr-1">Nachricht
0x83: WR an DTU (?): &#x201C;???&#x201D; (nach CMD w&#xE4;re das eher auch eine Antwort vom
WR?)</h3>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>Nachricht 0x83: WR an DTU (?): &quot;???&quot; (nach CMD w&#xE4;re das eher auch eine Antwort vom WR?)
----------------------------------------------------------------------------------------------------------------------------------------------

             95   72 22 02 00      72 22 02 00      83 00 03      00 83     03 E8     00 B2     00 0A     FD 26               1E  
             ^^   ^^^^^^^^^^^      ^^^^^^^^^^^      ^^                                                                        ^^  
Bedeutung    MID  WR ser#          WR ser#          CMD  ?         ?          ?         ?         ?         ?                 CRC8
Einheit           BCD (letzte 8)   BCD (letzte 8)        ?                                                   
Beispiel          72220200         72220200              ?        131       1000      178       10                                           </code></pre>
<h1 id="legend">Legend</h1>
<p><strong>MID</strong>: Message-ID. Antworten haben Bit 7 gesetzt,</p>
<ul>
<li>z.B. Frage <code>0x15</code> &#x2013;&gt; Antwort <code>0x95</code>.</li>
<li>z.B. Frage <code>0x07</code> &#x2013;&gt; Antwort <code>0x87</code>.</li>
</ul>
<p>F&#xFC;r Kommunikation GD &lt;&#x2013;&gt; NRF</p>
<p><strong>CMD</strong>:</p>
<p>Befehl an den WR hat Bit 7 gesetzt</p>
<ul>
<li><code>0x80</code> &#x201C;Zeit setzen&#x201D;</li>
<li><code>0x81</code> &#x201C;Anfrage DC-Daten&#x201D;, erwartete Antwort:
<code>0x01</code></li>
<li><code>0x82</code> &#x201C;Anfrage AC-Daten&#x201D;, erwartete Antwort:
<code>0x02</code></li>
<li><code>0x83</code> &#x201C;?&#x201D;</li>
<li><code>0x85</code> &#x201C;?&#x201D;</li>
<li><code>0xFF</code> &#x201C;?&#x201D;</li>
</ul>
<p>Antworten vom WR haben Bit 7 gel&#xF6;scht:</p>
<ul>
<li><code>0x01</code> &#x201C;Aktuelle DC-Daten&#x201D;</li>
<li><code>0x02</code> &#x201C;Aktuelle AC-Daten&#x201D;</li>
</ul>
<p><strong>SOF</strong>: Start-of-Frame <code>0x7E</code></p>
<p><strong>EOF</strong>: End-of-Frame <code>0x7F</code></p>
<p><strong>CRC8</strong>: CRC8 mit poly=1 init=0 xor=0, f&#xFC;r alle Bytes
zwischen SOF und CRC8.</p>
<p>Beispiel in Python:</p>
<pre class="language-text">```{.text data-role=&quot;codeBlock&quot; data-info=&quot;code&quot; data-parsed-info=&quot;{&amp;quot;language&amp;quot;:&amp;quot;code&amp;quot;,&amp;quot;attributes&amp;quot;:{}}&quot; data-normalized-info=&quot;{&amp;quot;language&amp;quot;:&amp;quot;code&amp;quot;,&amp;quot;attributes&amp;quot;:{}}&quot;}
  &gt;&gt;&gt; import crcmod
  &gt;&gt;&gt; f = crcmod.mkCrcFun(0x101, initCrc=0, xorOut=0)
  &gt;&gt;&gt; payload = bytes((0x95,0x72,0x22,0x02,0x00,0x72,0x22,0x02,0x00,0x83,0x00,0x03,0x00,0x83,0x03,0xE8,0x00,0xB2,0x00,0x0A,0xFD,0x26))
  &gt;&gt;&gt; hex(f(payload))
  &apos;0x1e&apos;
```</pre>
<p><strong>CRC_M</strong>: CRC16 wie f&#xFC;r &#x201C;Modbus&#x201D;-Protokoll, High-Byte
gefolgt von Low-Byte</p>
<p>Beispiel in Python:</p>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>  &gt;&gt;&gt; import crcmod
  &gt;&gt;&gt; f = crcmod.predefined.mkPredefinedCrcFun(&apos;modbus&apos;)
  &gt;&gt;&gt; payload = bytes((0x0B,0x00,0x62,0x2F,0x45,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00))
  &gt;&gt;&gt; hex(f(payload))
  &apos;0x3bd6&apos;</code></pre>
<p><strong>TIME</strong>: Aktuelle (DTU-)Zeit als Unix
<code>time_t</code> (Sekunden seit 1970-01-01)</p>
<h1 id="glossary">Glossary</h1>
<ul>
<li><p><strong>WR</strong>: Wechselrichter (inverter)</p></li>
<li><p><strong>DTU</strong>: Data Terminal Unit (?). Die
Hoymiles-Bezeichnung f&#xFC;r den Kommunikations-Master.</p></li>
<li><p><strong>BCD</strong>: Binary Coded Decimal</p></li>
</ul>
<h1 id="notizen">Notizen</h1>
<pre class="text language-text language-code" data-role="codeBlock" data-info="code"><code>0x014c = 332
0x03bd = 957
0x0c64 = 3172
0x6209049b = 1644758171
datetime.datetime.utcfromtimestamp(0x6209049b) =
datetime.datetime(2022, 2, 13, 13, 16, 11)</code></pre>
<h1 id="references">References</h1>
<ol type="1">
<li><a href="https://www.mikrocontroller.net/topic/525778">The post that
started the community effort</a></li>
<li><a href="https://www.mikrocontroller.net">mikrocontroller.net</a></li>
<li><a href="https://infocenter.nordicsemi.com/pdf/nRF24LE1_PS_v1.6.pdf">Nordic
NRF24LE01+ datasheet</a></li>
<li><a href="https://nrf24.github.io/RF24">Optimized high speed
nRF24L01+ driver documentation</a></li>
<li><a href="https://github.com/grindylow/ahoy/doc/Hoymiles-SerialNumbers.xlsx">Hoymiles-SerialNumbers.xlsx</a></li>
<li><a href="https://github.com/grindylow/ahoy">AHOY Communications
Project</a></li>
</ol>
<h1 id="revision-history">Revision History</h1>
<table>
<colgroup>
<col style="width: 12%">
<col style="width: 14%">
<col style="width: 10%">
<col style="width: 62%">
</colgroup>
<thead>
<tr class="header">
<th>Datum</th>
<th>Autor</th>
<th>Version</th>
<th>&#xC4;nderungen</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>2022-03-09</td>
<td>Petersilie</td>
<td>erste Version</td>
<td></td>
</tr>
<tr class="even">
<td>2022-03-10</td>
<td>Petersilie</td>
<td>r2</td>
<td>Nachrichten &#x201C;02 28 23&#x201D; und &#x201C;82 00 03&#x201D; erg&#xE4;nzt. Sauberer
ausgerichtet. Python Beispiel f&#xFC;r CRC.</td>
</tr>
<tr class="odd">
<td>2022-03-12</td>
<td>Petersilie</td>
<td>r3</td>
<td>Erste on-air Formate hinzu. CMD-IDs hinzu. Neue Nachrichten von
arnaldo_g hinzu. &#xDC;bersicht hinzu.</td>
</tr>
<tr class="even">
<td>2022-03-15</td>
<td>Petersilie</td>
<td>r4</td>
<td>Nachricht 0x80: Mystery-Bytes am Ende &#x201C;dechiffriert&#x201D;</td>
</tr>
<tr class="odd">
<td>2022-03-16</td>
<td>Petersilie</td>
<td>r5</td>
<td>ESP ist ein ESP8266, nicht ESP32 (danke an <span class="citation" data-cites="tbnobody">@tbnobody</span>)</td>
</tr>
<tr class="even">
<td>2022-03-27</td>
<td>Petersilie</td>
<td>Versionierung ab jetzt via Github.</td>
<td></td>
</tr>
<tr class="odd">
<td>2022-05-01</td>
<td>isnoAhoy</td>
<td>r7</td>
<td>Version als MarkDown formatiert, wavedrom Diagramme, HTML &amp; PDF
Export</td>
</tr>
</tbody>
</table>

      </div>
      
      
    
    
    
    <script>WaveDrom.ProcessAll()</script>
    
    
    
    
  
    </body></html>